﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using FeiXunHelper.Definitions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Drawing;
using FeiXunHelper.Definitions.Product;
using FeiXunHelper.Definitions.Address;
using FeiXunHelper.Definitions.User;

namespace FeiXunHelper.Services
{
    public class FeiXunService : AbstractService
    {
        private HttpCookie _cookie = null;
        private Dictionary<ProductCategory, Dictionary<string, string>> _cache = null;

        public FeiXunService()
        {
            _cookie = new HttpCookie();
            _cache = new Dictionary<ProductCategory, Dictionary<string, string>>();
            base.SetUserAgent("Mozilla/5.0 (Linux; Android 7.1.1; 1607-A01 Build/NMF26F; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.132 MQQBrowser/6.2 TBS/043906 Mobile Safari/537.36VMCHybirdAPP-Android");
            base.SetRequestEncoding(Encoding.UTF8);
        }

        public void SetCookie(string cookie)
        {
            _cookie.Clear();
            _cookie.SetCookie(cookie);
        }

        public string GetCookie()
        {
            return _cookie.ToString();
        }

        public void Login(string mobile, string pwd)
        {
            HttpResult result = null;
            string html = null;

            _cookie.Clear();
            result = Request(HttpMethod.Get, "https://mall.phicomm.com/m/passport-login.html", null, null, _cookie.ToString());
            _cookie.SetCookie(result.Cookie);

            List<KeyValuePair<string, object>> paras = new List<KeyValuePair<string, object>>();
            paras.Add(new KeyValuePair<string, object>("uname", mobile));
            paras.Add(new KeyValuePair<string, object>("password", pwd));
            paras.Add(new KeyValuePair<string, object>("forward", ""));
            base.AddRequestHeader("X-Requested-With", "XMLHttpRequest");
            result = Request(HttpMethod.Post, "https://mall.phicomm.com/m/passport-post_login.html",
                "https://mall.phicomm.com/m/passport-login.html", paras, _cookie.ToString());
            _cookie.SetCookie(result.Cookie);
            html = result.GetHtml();

        }

        public void CreateOrder(string productId, int productCount,AddressDetail addressInfo)
        {
            HttpResult result = null;
            string html = null;
            string cart_md5 = null;

            result = Request(HttpMethod.Get,
                string.Format("https://mall.phicomm.com/index.php/m/cart-fastbuy-{0}-{1}.html?", productId, productCount),
                string.Format("https://mall.phicomm.com/m/item-{0}.html", productId), null, _cookie.ToString());
            html = result.GetHtml();
            result = Request(HttpMethod.Get, "https://mall.phicomm.com/m/checkout-fastbuy.html", null, null, _cookie.ToString());
            html = result.GetHtml();
            // cart_md5:"eb5ec69f0e228e0a751aede1f3bf2cf1",
            int index1 = html.IndexOf("cart_md5:\"")+"cart_md5:\"".Length;
            int index2 = html.IndexOf("\"",index1);
            cart_md5 = html.Substring(index1, index2 - index1).Trim();
            List<KeyValuePair<string,object>> paras = new List<KeyValuePair<string,object>>();
            paras.Add(new KeyValuePair<string, object>("cart_md5", cart_md5));
            paras.Add(new KeyValuePair<string, object>("addr_id", addressInfo.addr_id));
            paras.Add(new KeyValuePair<string, object>("dlytype_id", "1"));
            paras.Add(new KeyValuePair<string, object>("payapp_id", "alipay"));
            paras.Add(new KeyValuePair<string, object>("need_invoice", "true"));
            paras.Add(new KeyValuePair<string, object>("invoice_title", "个人"));
            paras.Add(new KeyValuePair<string, object>("invoice_type", "0"));
            paras.Add(new KeyValuePair<string, object>("memo", ""));
            result = Request(HttpMethod.Post,
                "https://mall.phicomm.com/m/order-create-is_fastbuy.html",
                "https://mall.phicomm.com/m/checkout-fastbuy.html",paras,_cookie.ToString());
            html = result.GetHtml();
            if (!html.Contains("订单创建成功"))
            {
                JObject obj = JsonConvert.DeserializeObject(html) as JObject;
                if (!obj["success"].ToString().Contains("成功"))
                {
                    throw new Exception("创建订单失败！");
                }
            }
        }

        public List<AddressDetail> QueryAddressList()
        {
            var result = Request(HttpMethod.Get, "https://mall.phicomm.com/index.php/m/my-receiver.html ", null, null, _cookie.ToString());
            var html = result.GetHtml();
            string mark1 = "lists:[";
            string mark2 = "action";
            string mark3 = ",";
            int index1 = html.IndexOf(mark1) + mark1.Length-1;
            int index2 = html.IndexOf(mark2, index1);
            int index3 = html.LastIndexOf(mark3, index2);
            string json = html.Substring(index1, index3 - index1);
            return JsonConvert.DeserializeObject<List<AddressDetail>>(json);
        }

        public void SaveAddress(AddressBrief address)
        {
            List<KeyValuePair<string,object>> paras = new List<KeyValuePair<string,object>>();
            paras.Add(new KeyValuePair<string,object>("maddr[addr_id]","null"));
            paras.Add(new KeyValuePair<string,object>("maddr[name]",address.Name));
            paras.Add(new KeyValuePair<string,object>("maddr[mobile]",address.Mobile));
            paras.Add(new KeyValuePair<string,object>("maddr[area]",string.Format("mainland:{0}/{1}/{2}:12",address.Province,address.City,address.Country)));
            paras.Add(new KeyValuePair<string,object>("maddr[addr]",address.Street));
            paras.Add(new KeyValuePair<string,object>("maddr[is_default]","null"));
            HttpResult result = Request(HttpMethod.Post,"https://mall.phicomm.com/m/my-receiver-save.html",
                "https://mall.phicomm.com/m/my-receiver-edit.html",paras,_cookie.ToString());
            string html = result.GetHtml();
            if(!html.Contains("保存成功"))
            {
                throw new Exception("保存收货地址失败！");
            }
        }

        public UserInfo QueryUserInfo()
        {
            HttpResult result = Request(HttpMethod.Get, "https://mall.phicomm.com/m/my-setting.html", null, null, _cookie.ToString());
            string html = result.GetHtml();
            if (html.Contains("会员登录"))
            {
                // 未登陆状态
                return null;
            }
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(html);
            string mark1 = "class=\"form-control]\"";
            string mark2 = "value=\"";
            string mark3 = "\"";
            int index1 = html.IndexOf(mark1) + mark1.Length;
            index1 = html.IndexOf(mark2, index1) + mark2.Length;
            int index2 = html.IndexOf(mark3, index1);
            string mobile = html.Substring(index1, index2 - index1);

            UserInfo ui = new UserInfo();
            ui.Mobile = mobile;
            return ui;
        }

        public List<ProductBrief> QueryProductBriefList(ProductCategory category)
        {
            var goodsIdList = QueryGoodsIdList(category);
            var productBriefList = QueryProductBriefList(goodsIdList);
            return productBriefList;
        }

        public List<ProductDetail> QueryProductDetailList(ProductCategory category)
        {
            List<ProductDetail> list = new List<ProductDetail>();
            if (!_cache.ContainsKey(category))
            {
                var goodsIdList = QueryGoodsIdList(category);
                var productBriefList = QueryProductBriefList(goodsIdList);
                _cache.Add(category, new Dictionary<string, string>());
                foreach (var item in productBriefList)
                {
                    _cache[category].Add(item.goods_id, item.product.product_id);
                }
            }
            foreach (var item in _cache[category])
            {
                var productId = item.Value;
                var productDetail = QueryProductDetail(productId);
                list.Add(productDetail);
            }
            return list;
        }

        private List<string> QueryGoodsIdList(ProductCategory category)
        {
            string url = category.Id;
            HttpResult result = Request(HttpMethod.Get, url, "https://mall.phicomm.com/m/index.html", null, _cookie.ToString());
            _cookie.SetCookie(result.Cookie);
            string html = result.GetHtml();
            string mark1 = "PAGE_DATA___";
            string mark2 = "{";
            string mark3 = ";";
            int index1 = html.IndexOf(mark1) + mark1.Length;
            int index2 = html.IndexOf(mark2, index1);
            int index3 = html.IndexOf(mark3, index2);
            string json = html.Substring(index2, index3 - index2);
            JObject obj = JsonConvert.DeserializeObject(json) as JObject;
            JArray arr = obj["widgets"] as JArray;
            List<string> productIds = null;
            for (int i = 0; i < arr.Count; i++)
            {
                obj = arr[i] as JObject;
                string name = obj["name"].ToString();
                if (name == "goodslist")
                {
                    json = obj["data"]["filter"]["goods_id"].ToString();
                    productIds = JsonConvert.DeserializeObject<List<string>>(json);
                    break;
                }
            }

            return productIds;
        }

        private List<ProductBrief> QueryProductBriefList(List<string> goodsIdList)
        {
            string url = "https://mall.phicomm.com/openapi/goods/gallery/";
            List<KeyValuePair<string, object>> paras = new List<KeyValuePair<string, object>>();
            paras.Add(new KeyValuePair<string, object>("page_index", 1));
            paras.Add(new KeyValuePair<string, object>("page_size", 9));
            foreach (var productId in goodsIdList)
            {
                paras.Add(new KeyValuePair<string, object>("filter[goods_id][]", productId));
            }
            HttpResult result = Request(HttpMethod.Get, url, null, paras, _cookie.ToString());
            _cookie.SetCookie(result.Cookie);
            string html = result.GetHtml();
            JObject obj = JsonConvert.DeserializeObject(html) as JObject;
            string json = obj["data"]["goods_list"].ToString();
            return JsonConvert.DeserializeObject<List<ProductBrief>>(json);
        }

        public ProductDetail QueryProductDetail(string productId)
        {
            string url = string.Format("https://mall.phicomm.com/m/item-{0}.html", productId);
            HttpResult result = Request(HttpMethod.Get, url, null, null, _cookie.ToString());
            _cookie.SetCookie(result.Cookie);
            string html = result.GetHtml();
            string mark1 = "details:";
            string mark2 = "comments:";
            string mark3 = "}";
            int index1 = html.IndexOf(mark1) + mark1.Length;
            int index2 = html.IndexOf(mark2, index1);
            int index3 = html.LastIndexOf(mark3, index2) + 1;
            string json = html.Substring(index1, index3 - index1);
            return JsonConvert.DeserializeObject<ProductDetail>(json);
        }

        public string GetProductDetailUrl(string productId)
        {
            string url = string.Format("https://mall.phicomm.com/m/item-{0}.html", productId);
            return url;
        }

        public Image DownloadImage(String url)
        {
            var result = Request(HttpMethod.Get, url, null, null, null);
            return result.GetImage();
        }
    }
}
